﻿package org.dm.3d.render 
{
	import flash.display.Shape;
	import flash.events.Event;
	import flash.geom.Point;
	import org.dm.3d.Actions.Action;
	import org.dm.3d.Actions.cameras.CAction;
	import org.dm.3d.cameras.CameraBase;
	import org.dm.3d.geom.Num3D;
	import org.dm.3d.object.Bitmap.roundMap;
	import org.dm.3d.object.Works.Work;
	
	
	/**
	 * ...
	 * @author Scott
	 */
	public class RenderBitmap extends Shape
	{
		private var _items:Array;
		private var _num:uint;
		private var _itemsAction:Action;
		private var _camera:CameraBase;
		private var _cameraAction:CAction;
		public var flen:Number = 800;
		private var PI:Number = Math.PI;
		public var viewLimte:Boolean = false;
		private var _physics:Boolean = true;
		
		public function RenderBitmap(pcamera:CameraBase,pitem:Array) 
		{
			_camera = pcamera;
			_items = pitem;
			_num = _items.length;
			_itemsAction = new Action();
			_cameraAction = new CAction();
			addEventListener(Event.ENTER_FRAME, update);
		}
		public function reset():void 
		{
			for (var i:uint = 0; i < _num; i++)
			{
				_items[i].speed = new Num3D();
				_items[i].acceleration = new Num3D();
				_items[i].damping = .95;
			    _items[i].visable = true;
			}
		}
		public function pause():void
		{
			_itemsAction.isUsed = false;
			_cameraAction.isUsed = false;
			_physics = false;
		}
		public function resume():void 
		{
			_itemsAction.isUsed = true;
			_cameraAction.isUsed = true;
			_physics = true;
		}
		public function stop():void
		{
			removeEventListener(Event.ENTER_FRAME, update);
		}
		public function start():void
		{
			addEventListener(Event.ENTER_FRAME, update);
		}
		public function setItemAction(action:Action):void
		{
			this.reset();
			_itemsAction = action;
		}
		
		public function disEAction():void
		{
			_itemsAction.isUsed = false;
		}
		
		public function setCAction(action:CAction):void 
		{
			if (_cameraAction != null) _cameraAction = null;
			_cameraAction = action;
		}
		public function stopCAction():void
		{
			_cameraAction.isUsed = false;
		}
		public function startCAction():void
		{
			_cameraAction.isUsed = true;
		}
		public function transformToplane(v:Vector.<Num3D>):Vector.<Number>
		{
			var scale:Number;
			var cpos:Num3D;
			var dis:Number;
			var angleX:Number = _camera.angle.x;
			var angleY:Number = _camera.angle.y;
			var angleZ:Number = _camera.angle.z;
			var xSin:Number = Math.sin(angleX);
			var xCos:Number = Math.cos(angleX);
			var ySin:Number = Math.sin(angleY);
			var yCos:Number = Math.cos(angleY);
			var zSin:Number = Math.sin(angleZ);
			var zCos:Number = Math.cos(angleZ);
			var tempx:Number;
			var tempy:Number;
			var imax:uint = v.length;
			var result:Vector.<Number> = new Vector.<Number>();
			for (var i:uint = 0; i < imax; i++)
			{
				cpos = v[i].subtract(_camera.pos);
				tempx = xCos*cpos.x - xSin*cpos.z;
				tempy = xSin*cpos.x + xCos*cpos.z;
				cpos.x = tempx;
				cpos.z = tempy;
				
				tempx = yCos*cpos.y - ySin*cpos.z;
				tempy = ySin*cpos.y + yCos*cpos.z;
				cpos.y = tempx;
				cpos.z = tempy;
				
				tempx = zCos*cpos.x - zSin*cpos.y;
				tempy = zSin*cpos.x + zCos*cpos.y;
				cpos.x = tempx;
				cpos.y = tempy;
				
				scale = flen / (flen + cpos.z);
				cpos.x *= scale;
				cpos.y *= scale;
				result.push(cpos.x+350, cpos.y+185);
			}
			return result;
		}
		public function physicalMove():void
		{
			var tball:roundMap;
			for (var i:uint = 0; i <_num; i++)
			{
				tball = _items[i] as roundMap;
				tball.speed.incrementBy(tball.acceleration);
				tball.pos.incrementBy(tball.speed);				
				tball.speed.scaleBy(tball.damping);
			}
			_camera.angleSpeed.incrementBy(_camera.angleA);
			_camera.angle.incrementBy(_camera.angleSpeed);
			_camera.angleSpeed.scaleBy(_camera.damping);
			_camera.angle.x -= _camera.angle.x > PI * 2?PI * 2:0;
			_camera.angle.y -= _camera.angle.y > PI * 2?PI * 2:0;
			_camera.angle.z -= _camera.angle.z > PI * 2?PI * 2:0;
			if (Math.abs(_camera.angle.x) > .8) _camera.angleSpeed.x = -.9 * _camera.angleSpeed.x;
			if (Math.abs(_camera.angle.y) > .4) _camera.angleSpeed.y = -.9 * _camera.angleSpeed.y;
			//if(viewLimte&&_camera.angle.y > -.4&&_camera.angle.y <0) _camera.angleSpeed.y = -.5 * _camera.angleSpeed.y;
		}
		public function update(e:Event):void
		{
			if(_physics) physicalMove();
			if (_itemsAction.isUsed) _itemsAction.update(_items,_num);
			if (_cameraAction.isUsed) _cameraAction.update(_camera);
			var scale:Number;
			var cpos:Num3D;
			var dis:Number;
			var angleX:Number = _camera.angle.x;
			var angleY:Number = _camera.angle.y;
			var angleZ:Number = _camera.angle.z;
			var xSin:Number = Math.sin(angleX);
			var xCos:Number = Math.cos(angleX);
			var ySin:Number = Math.sin(angleY);
			var yCos:Number = Math.cos(angleY);
			var zSin:Number = Math.sin(angleZ);
			var zCos:Number = Math.cos(angleZ);
			var tempx:Number;
			var tempy:Number;
			var color:uint;
			this.graphics.clear();
			for (var i:uint = 0; i <_num; i++)
			{
				cpos = _items[i].pos.subtract(_camera.pos);
				tempx = xCos*cpos.x - xSin*cpos.z;
				tempy = xSin*cpos.x + xCos*cpos.z;
				cpos.x = tempx;
				cpos.z = tempy;
				
				tempx = yCos*cpos.y - ySin*cpos.z;
				tempy = ySin*cpos.y + yCos*cpos.z;
				cpos.y = tempx;
				cpos.z = tempy;
				
				tempx = zCos*cpos.x - zSin*cpos.y;
				tempy = zSin*cpos.x + zCos*cpos.y;
				cpos.x = tempx;
				cpos.y = tempy;
				
				if (cpos.z < -400+2*_camera.pos.z) 
				{
					_items[i].visable = false;
				}
				else
					_items[i].visable = true;
				/**/
				if (!_items[i].visable) continue;
				scale = flen / (flen + cpos.z);
				cpos.x *= scale;
				cpos.y *= scale;
				dis = _items[i].radius * scale;
				color = 0xffffff;
				if (cpos.z > 400) color -= 2 * int(cpos.z / 50) * 1118481;
				if (cpos.z < -200) color -= int( -cpos.z / 50) * 1118481;
				this.graphics.beginFill(color, 1);
				this.graphics.drawCircle(cpos.x, cpos.y, dis);
				this.graphics.endFill();
			}
		}
	}
	
}